package main

import (
	"errors"
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	"github.com/tealeg/xlsx"
	"strconv"
)

type Student struct {

	Name   string
	Age    int
	Phone  string
	Gender string
	Mail   string
}

// HeaderColumn 表头字段定义
type HeaderColumn struct {

	Field string // 字段，数据映射到的数据字段名
	Title string // 标题，表格中的列名称
}


// SetHeader 写模式下，设置字段表头和字段顺序
// 参数 header 为表头和字段映射关系，如：HeaderColumn{Field:"title", Title: "标题", Requre: true}
// 参数 width  为表头每列的宽度，单位 CM：map[string]float64{"title": 0.8}
func SetHeader(sheet *xlsx.Sheet, header []*HeaderColumn, width map[string]float64) (*xlsx.Sheet, error) {
	if len(header) == 0 {
		return nil, errors.New("Excel.SetHeader 错误: 表头不能为空")
	}

	// 表头样式
	style := xlsx.NewStyle()

	font := xlsx.DefaultFont()
	font.Bold = true

	alignment := xlsx.DefaultAlignment()
	alignment.Vertical = "center"

	style.Font = *font
	style.Alignment = *alignment

	style.ApplyFont = true
	style.ApplyAlignment = true

	// 设置表头字段
	row := sheet.AddRow()
	row.SetHeightCM(1.0)
	row_w := make([]string, 0)
	for _, column := range header {
		row_w = append(row_w, column.Field)
		cell := row.AddCell()
		cell.Value = column.Title
		cell.SetStyle(style) //设置单元样式
	}

	// 表格列，宽度
	if len(row_w) > 0 {
		for k, v := range row_w {
			if width[v] > 0.0 {
				sheet.SetColWidth(k, k, width[v]*10)
			}
		}
	}

	return sheet, nil
}

// 准备数据
func getStudents() []Student {
	students := make([]Student, 0)
	for i := 0; i < 10; i++ {
		stu := Student{}
		stu.Name = "love" + strconv.Itoa(i+1)
		stu.Mail = stu.Name + "@studygolang.com"
		stu.Phone = "100867" + strconv.Itoa(i)
		stu.Age = 18 + i
		if i%2 == 0 {
			stu.Gender = "女"
		} else {
			stu.Gender = "男"
		}

		students = append(students, stu)
	}
	return students
}


func Export() {
	file := xlsx.NewFile()                      // NewWriter 创建一个Excel写操作实例
	sheet, err := file.AddSheet("student_list") //表实例
	if err != nil {
		fmt.Printf(err.Error())
	}
	stus := getStudents() //add data

	headers := []*HeaderColumn{
		{Field: "Name", Title: "姓名"},
		{Field: "Age", Title: "年龄"},
		{Field: "Phone", Title: "电话"},
		{Field: "Gender", Title: "性别"},
		{Field: "Mail", Title: "邮箱"},
	}
	style := map[string]float64{
		"Name":   2.0,
		"Age":    2.0,
		"Phone":  2.0,
		"Gender": 2.0,
		"Mail":   2.0,
	}
	sheet, _ = SetHeader(sheet, headers, style)

	for _, stu := range stus {
		data := make(map[string]string)
		data["Name"] = stu.Name
		data["Age"] = strconv.Itoa(stu.Age)
		data["Phone"] = stu.Phone
		data["Gender"] = stu.Gender
		data["Mail"] = stu.Mail

		row := sheet.AddRow()
		row.SetHeightCM(0.8)
		for _, field := range headers {
			row.AddCell().Value = data[field.Field]
		}
	}
	outFile := "./out_student.xlsx"
	err = file.Save(outFile)
	if err != nil {
		fmt.Printf(err.Error())
	}
	fmt.Println("\n\nexport success")
}




func main() {
	Export()
	f := excelize.NewFile()
	// 创建一个工作表
	index := f.NewSheet("Sheet1")

	//隐藏名称为 Sheet1 的工作表中的 D 至 F 列：
	f.SetColVisible("Sheet1", "D:F", false)

	//根据给定的工作表名称（大小写敏感）、列范围和宽度值设置单个或多个列的宽度。
	//例如设置名为 Sheet1 工作表上 A 到 D 列的宽度为 20：
	f.SetColWidth("Sheet1", "A", "D", 20)

	//根据给定的工作表名称（大小写敏感）、行号和高度值设置单行高度。
	//例如设置名为 Sheet1 工作表第二行行的高度为 50：
	f.SetRowHeight("Sheet1", 2, 50)

	// 设置单元格的值
	f.SetCellValue("Sheet1", "A2", 100)

	//根据给定的工作表名（大小写敏感）和单元格坐标区域合并单元格。例如，合并名为 Sheet1 的工作表上 D3:E9 区域内的单元格：
	f.MergeCell("Sheet1", "D3", "D4")


	f.SetCellValue("Sheet1", "D3", 1000)
	f.SetCellValue("Sheet1", "D5", "hello")

	// 设置工作簿的默认工作表
	f.SetActiveSheet(index)
	// 根据指定路径保存文件
	if err := f.SaveAs("Book1.xlsx"); err != nil {
		println(err.Error())
	}
}

